package com.vaha.presentation.rest;

import com.alibaba.fastjson.JSONObject;
import com.cyber.application.controller.AuthingTokenController;
import com.cyber.domain.constant.HttpResultCode;
import com.cyber.domain.entity.*;
import com.vaha.application.service.ProductFollowService;
import com.vaha.application.service.ProductItemService;
import com.vaha.application.service.ProductService;
import com.vaha.domain.entity.Product;
import com.vaha.domain.entity.ProductFollow;
import com.vaha.domain.entity.ProductItem;
import com.vaha.domain.request.CreateProductFollowRequest;
import com.vaha.domain.request.ProductFollowRequest;
import com.vaha.domain.request.UpdateProductFollowRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequiredArgsConstructor
public class ProductFollowRest extends AuthingTokenController {

    private final ProductService productService;

    private final ProductItemService productItemService;

    private final ProductFollowService productFollowService;

    private final List<Integer> userOper = Arrays.asList(1,2,3);

    @GetMapping("/user/productfollow/search")
    public Response searchUserProductFollow(@Valid ProductFollowRequest request) {
        DataResponse<PagingData<ProductFollow>> response = new DataResponse<>();
        ProductFollow productfollow = request.toEvent(getTenantCode());

        JSONObject user = getUser();
        productfollow.setUserCode(user.getString("code"));
        PagingData<ProductFollow> productFollowPage = productFollowService.selectPage(productfollow);

        if (!CollectionUtils.isEmpty(productFollowPage.getData())) {
            List<String> productCodes = productFollowPage.getData().stream().map(ProductFollow::getProductCode).collect(Collectors.toList());
            List<Product> productList = productService.selectByCodes(productCodes);
            if (!CollectionUtils.isEmpty(productList)) {

                Map<String, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getCode, product -> product));

                for (ProductFollow datum : productFollowPage.getData()) {
                    Product product = productMap.getOrDefault(datum.getProductCode(), null);
                    datum.setProduct(product);
                }
            }

            List<String> productItemCodes = productFollowPage.getData().stream().map(ProductFollow::getProductItemCode).collect(Collectors.toList());
            List<ProductItem> productItemList = productItemService.selectByCodes(productItemCodes);
            if (!CollectionUtils.isEmpty(productItemList)) {

                Map<String, ProductItem> productItemMap = productItemList.stream().collect(Collectors.toMap(ProductItem::getCode, productItem -> productItem));

                for (ProductFollow datum : productFollowPage.getData()) {
                    ProductItem productItem = productItemMap.getOrDefault(datum.getProductItemCode(), null);
                    datum.setProductItem(productItem);
                }
            }

        }

        response.setData(productFollowPage);
        return response;
    }

    @GetMapping("/user/productfollow")
    public Response selectOneUserProductFollow(@Valid IdRequest idRequest) {
        DataResponse<ProductFollow> response = new DataResponse<>();

        ProductFollow productFollow = new ProductFollow();
        productFollow.setId(idRequest.getId());
        productFollow.setTenantCode(getTenantCode());
        productFollow = productFollowService.selectOne(productFollow);

        if (Objects.isNull(productFollow)) {
            return response;
        }
        Product product = new Product();
        product.setType(productFollow.getProductType());
        product.setCode(productFollow.getProductCode());
        product = productService.selectOne(product);

        if (Objects.isNull(product)) {
            return response;
        }
        productFollow.setProduct(product);

        ProductItem productItem = new ProductItem();
        productItem.setCode(productFollow.getProductItemCode());

        productItem = productItemService.selectOne(productItem);
        productFollow.setProductItem(productItem);

        response.setData(productFollow);
        return response;
    }

    @PostMapping("/user/productfollow")
    public Response saveUserProductFollow(@RequestBody @Valid CreateProductFollowRequest request) {

        if (!userOper.contains(request.getType())) {
            return Response.fail(HttpResultCode.PARAM_ERROR);
        }

        ProductFollow productfollow = request.toEvent(getSessionId(), getTenantCode());
        JSONObject user = getUser();
        productfollow.setUserCode(user.getString("code"));

        if (!productFollowService.checkProductFollowUnique(productfollow)) {
            if (3 == productfollow.getType()) {
                productfollow = productFollowService.selectOne(productfollow);
                productfollow.setUpdateTime(new Date());
                int result = productFollowService.updateById(productfollow);
                if (result < 1) {
                    return Response.fail(HttpResultCode.SERVER_ERROR);
                }
                return Response.success();
            }
            return Response.fail(HttpResultCode.RECORD_EXIST);
        }
        productfollow = request.toEvent(getSessionId(), getTenantCode());
        productfollow.setUserCode(user.getString("code"));

        int result = productFollowService.save(productfollow);
        if (result < 1) {
            return Response.fail(HttpResultCode.SERVER_ERROR);
        }
        return Response.success();
    }

    @PutMapping("/user/productfollow/cancel")
    public Response updateUserProductFollow(@RequestBody @Valid UpdateProductFollowRequest request) {

        if (!userOper.contains(request.getType())) {
            return Response.fail(HttpResultCode.PARAM_ERROR);
        }

        ProductFollow productFollow = new ProductFollow();
        JSONObject user = getUser();
        productFollow.setUserCode(user.getString("code"));
        productFollow.setProductCode(request.getProductCode());
        productFollow.setProductType(request.getProductType());
        productFollow.setProductItemCode(request.getProductItemCode());
        productFollow.setType(request.getType());

        productFollow = productFollowService.selectOne(productFollow);

        if (Objects.isNull(productFollow)) {
            return Response.fail(HttpResultCode.RECORD_NOT_EXIST);
        }

        int result = productFollowService.deleteById(productFollow);
        if (result < 1) {
            return Response.fail(HttpResultCode.SERVER_ERROR);
        }
        return Response.success();
    }

    @GetMapping("/admin/productfollow/search")
    public Response searchProductFollow(@Valid ProductFollowRequest request) {
        DataResponse<PagingData<ProductFollow>> response = new DataResponse<>();
        ProductFollow productfollow = request.toEvent(getTenantCode());
        PagingData<ProductFollow> productFollowPage = productFollowService.selectPage(productfollow);
        response.setData(productFollowPage);
        return response;
    }


    @GetMapping("/admin/productfollow")
    public Response selectOneProductFollow(@Valid IdRequest idRequest) {
        DataResponse<ProductFollow> response = new DataResponse<>();

        ProductFollow productFollow = new ProductFollow();
        productFollow.setId(idRequest.getId());
        productFollow.setTenantCode(getTenantCode());
        productFollow = productFollowService.selectOne(productFollow);

        response.setData(productFollow);
        return response;
    }

    @PostMapping("/admin/productfollow")
    public Response saveProductFollow(@RequestBody @Valid CreateProductFollowRequest request) {
        ProductFollow productfollow = request.toEvent(getSessionId(), getTenantCode());

        int result = productFollowService.save(productfollow);
        if (result < 1) {
            return Response.fail(HttpResultCode.SERVER_ERROR);
        }
        return Response.success();
    }

    @PutMapping("/admin/productfollow")
    public Response updateProductFollow(@RequestBody @Valid UpdateProductFollowRequest request) {
        ProductFollow productfollow = request.toEvent(getSessionId(), getTenantCode());
        int result = productFollowService.updateById(productfollow);
        if (result < 1) {
            return Response.fail(HttpResultCode.SERVER_ERROR);
        }
        return Response.success();
    }

    @DeleteMapping("/admin/productfollow")
    public Response deleteProductFollow(@Valid IdRequest idRequest) {
        ProductFollow productFollow = new ProductFollow();
        productFollow.setId(idRequest.getId());

        productFollow.setTenantCode(getTenantCode());
        productFollow.setUpdator(getSessionId());
        productFollow.setUpdateTime(new Date());

        int result = productFollowService.deleteById(productFollow);
        if (result < 1) {
            return Response.fail(HttpResultCode.SERVER_ERROR);
        }
        return Response.success();
    }
}
